<?php

declare(strict_types=1);

namespace App\Service\Logic;

use App\Constants\Menu\MenuStatusEnum;
use App\Constants\Role\RoleStatusEnum;
use App\Validator\CommonValidator;
use Exception;
use Hyperf\Di\Annotation\Inject;
use App\Service\Business\MenuBusiness;
use App\Validator\MenuValidator;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

/**
 * 菜单-逻辑类
 */
class MenuLogic extends BaseLogic
{
        #[Inject]
        protected MenuBusiness $MenuBusiness;

        #[Inject]
        protected MenuValidator $MenuValidator;

        #[Inject]
        protected CommonValidator $CommonValidator;

        /**
         * 分页
         * @return array
         * @throws Exception
         */
        public function paginate(): array
        {
                $this->CommonValidator->validate($this->request->all(), ['page', 'limit']);
                $arrInject = [];
                if (!in_array($this->request->getAttribute('userId'), [1, 'xx'])) {#非总管理员或xx加限定条件
                        $arrInject['mergeWheres'] = [
                                'userId' => $this->request->getAttribute('userId'),
                                'status' => MenuStatusEnum::DEFINITION_1->value,
                                'roleStatus' => RoleStatusEnum::DEFINITION_1->value,
                        ];
                        $arrInject['joins'] = [
                                'role_menu' => [
                                        'table' => 'role_menu',
                                        'on' => function ($join) {
                                                $join->on('role_menu.menuId', '=', 'menu.menuId');
                                        }
                                ],
                                'role' => [
                                        'table' => 'role',
                                        'on' => function ($join) {
                                                $join->on('role.roleId', '=', 'role_menu.roleId');
                                        }
                                ],
                                'user_role' => [
                                        'table' => 'user_role',
                                        'on' => function ($join) {
                                                $join->on('user_role.roleId', '=', 'role.roleId');
                                        }
                                ]
                        ];
                }
                return $this->MenuBusiness->paginate($arrInject);
        }

        /**
         * 创建
         * @return array
         * @throws ContainerExceptionInterface
         * @throws NotFoundExceptionInterface
         * @throws Exception
         */
        public function create(): array
        {
                $this->CommonValidator->validate($this->request->all(), ['sort']);
                $this->MenuValidator->validate($this->request->all(), ['name', 'title', 'method', 'status', 'type',
                        'isHide', 'isHideTab', 'isKeepAlive', 'isFixedTab', 'isIframe', 'isBadge', 'belongTo'],
                        ['pid', 'route', 'path', 'activePath', 'link', 'icon', 'permissionMark', 'queryParams',
                                'pathParams', 'badgeText']);
                return $this->MenuBusiness->create();
        }

        /**
         * 更新
         * @return array
         * @throws ContainerExceptionInterface
         * @throws NotFoundExceptionInterface
         * @throws Exception
         */
        public function update(): array
        {
                $this->CommonValidator->validate($this->request->all(), ['sort']);
                $this->MenuValidator->validate($this->request->all(), ['menuId', 'name', 'title', 'method', 'status',
                        'type', 'isHide', 'isHideTab', 'isKeepAlive', 'isFixedTab', 'isIframe', 'isBadge', 'belongTo'],
                        ['pid', 'route', 'path', 'activePath', 'link', 'icon', 'permissionMark',  'queryParams',
                                'pathParams', 'badgeText']);
                $intMenuId = intval($this->request->input('menuId', 0));
                $intPid = intval($this->request->input('pid', 0));
                if ($intPid === $intMenuId) throw new Exception(trans('menu.tip.parentCannotSelf'));
                $intState = intval($this->request->input('status'));
                if ($intState === MenuStatusEnum::DEFINITION_1->value && $intPid) {
                        $boolCheck = $this->MenuBusiness->exists(['wheres' => ['menuId' => $intPid,
                                'status' => MenuStatusEnum::DEFINITION_2->value]]);
                        if ($boolCheck) throw new Exception(trans('menu.tip.parentIsDisabled'));
                } elseif ($intState === MenuStatusEnum::DEFINITION_2->value) {
                        $boolCheck = $this->MenuBusiness->exists(['wheres' => ['pid' => $intMenuId,
                                'status' => MenuStatusEnum::DEFINITION_1->value]]);
                        if ($boolCheck) throw new Exception(trans('menu.tip.childIsNormal'));
                }
                return $this->MenuBusiness->update();
        }
}